/* 08-mutex.c

   Illustration of thread synchronization using mutex variables.
   mutex variables can be initialized with the 
      PTHREAD_MUTEX_INITIALIZER
   macro as shown.  Also pthread_self is used for the first time.

   In this example, 10 threads contribute to incrementing a counter.

   pthread.h should be first otherwise compile with -D_THREAD_SAFE 
*/
#include <pthread.h>
#include <stdio.h>

#define NTHREADS 10

/* The PTHREAD_MUTEX_INITIALIZER macro initializes the static mutex, 
   setting its attributes to default values. This macro should only be used 
   for static mutexes, as no error checking is performed. */
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;  

void *thread_function(void *dummyPtr) {
   printf("Thread number %x\n", pthread_self());
   pthread_mutex_lock( &mutex1 );
   counter++;
   pthread_mutex_unlock( &mutex1 );
   return NULL;
}

int main() {
   pthread_t thread_id[NTHREADS];
   int i, j;

   for (i=0; i < NTHREADS; i++)
      pthread_create( &thread_id[i], NULL, thread_function, NULL );

   for (j=0; j < NTHREADS; j++)
      pthread_join( thread_id[j], NULL);

   /* Now that all threads are complete I can print the final result.     */
   /* Without the join I could be printing a value before all the threads */
   /* have been completed.                                                */

   printf("Final counter value: %d\n", counter);
}

